<template>
    <div class="iframe-full">
        <div class="iframe-preview">
            <div class="head">
                <div class="top">
                    <span class="time">10:00</span>
                    <div class="icons">
                        <img src="@/assets/mall/micon.png" class="micon" /><img
                            src="@/assets/mall/dicon.png"
                            class="dicon" /><img src="@/assets/mall/picon.png" class="picon" />
                    </div>
                </div>
                <div class="bottom" @click="changeTOhead">
                    <div class="shopname elispse">
                        <span v-if="pageParam.data.isHomePage == 1">{{ shopName }} </span>
                    </div>
                    <div class="name elispse">{{ pageParam.data.templateDesc }}</div>
                    <div class="bicon"><img src="@/assets/mall/bicon.png" class="sicon" /></div>
                </div>
            </div>
            <div v-if="pageParam.data.isHomePage == 3">
                <img :src="payresultImg" onerror="@/assets/mall/bicon.png" class="payImg" />
            </div>
            <div class="content">
                <div class="component-list">
                    <draggable :list="components" :options="sortOptions" item-key="id" style="width: 100%">
                        <template #item="{ element, index }">
                            <div
                                v-if="element?.options?.name !== 'PlaceHolderView'"
                                :class="['component-body', index == currentIndex ? 'focus-body' : '']"
                                :tabindex="index"
                                :id="`body${element.id}`"
                                @mouseover="mouseover(index)"
                                @mouseleave="mouseleave(index)"
                                @click="componentFocusHandler(element, index)">
                                <div class="component-left" :id="`left${element.id}`">
                                    {{ element.title }}
                                </div>
                                <div class="component-center">
                                    <component
                                        class="component-item"
                                        :is="element.component"
                                        :options="element.options"
                                        :id="`com${element.id}`">
                                    </component>
                                </div>
                                <div class="component-right" :id="`right${element.id}`">
                                    <div class="icons">
                                        <img
                                            src="@/assets/mall/up.png"
                                            @click="operate($event, 1, index)"
                                            v-show="index" />
                                        <img
                                            src="@/assets/mall/down.png"
                                            @click="operate($event, 2, index)"
                                            v-show="index + 1 != components.length" />
                                        <img src="@/assets/mall/del.png" @click="operate($event, 3, index)" />
                                    </div>
                                </div>
                            </div>
                        </template>
                    </draggable>
                </div>
            </div>
        </div>
    </div>
</template>
<script setup>
import { ref, reactive, getCurrentInstance, nextTick, onMounted, onBeforeUnmount } from 'vue';
import IframeMessage from '@/commons/iframeMessage';
import { getComponentByName } from '@/components';
import draggable from 'vuedraggable';
import { getUuid, getUrlParam } from '@/commons/utils';
import request from '@/request';
import { isNotEmpty, floatDivide } from '../../commons/utils';
let currentIndex = ref(-1);
let addIndex = ref(-1);
const instance = getCurrentInstance();
let components = ref([]); //组件数据
let shopName = ref(); //店铺名称
let payresultImg = ref(); //支付结果默认图片
const iframeMessage = new IframeMessage(window.parent, `${import.meta.env.VITE_SHOP_CLOUD_HOST}`);
let pageParam = reactive({
    data: {
        pageCode: '',
        templateName: '',
        templateDesc: '',
        shareImg: '',
        shareTitle: '',
        status: 2,
        isShare: 2,
        isHomePage: '2'
    }
});
const sortOptions = reactive({
    animation: 150,
    ghostClass: 'sortable-ghost',
    chosenClass: 'sortable-chosen',
    dragClass: 'sortable-drag'
});

/**
 * 监听元素进入目标区域
 */
iframeMessage.on('dragenter', () => {
    let r = components.value.findIndex(item => item.component.name === 'PlaceHolderView');
    let index = components.value.length;
    if (r > -1) {
        index--;
    }
    addPlaceholderViewHanlder(index);
});

/**
 * 监听元素离开目标区域
 */
iframeMessage.on('dragleave', () => {
    removePlaceholderViewHandler();
});

/**
 * 改变iframe高度
 */
const changeIframeHeight = () => {
    nextTick(() => {
        let heightArr = [];
        components.value.forEach((res, i) => {
            uni.createSelectorQuery()
                .in(instance)
                .select('#com' + res.id)
                .boundingClientRect(data => {
                    heightArr.push(data.height);
                })
                .exec();
        });
        // 支付结果页高度
        if (pageParam.data.isHomePage == 3) {
            heightArr.splice(0, 0, '254');
        }
        iframeMessage.emit('changeMaskHeight', heightArr);
        uni.createSelectorQuery()
            .in(instance)
            .select('.iframe-full')
            .boundingClientRect(data => {
                iframeMessage.emit('changeIframeHeight', data.height);
            })
            .exec();
    });
};
/**
 *控制隐藏显示工具栏
 * @param {*} index
 * @param {*} type
 * @param {*} display
 */
const changeToolDisplayHandler = (id, display = 'inline-block') => {
    const allRightDom = document.querySelectorAll(`.component-right`);
    const allLeftDom = document.querySelectorAll(`.component-left`);
    for (let item of allLeftDom) {
        item.style.display = 'none';
    }
    for (let item of allRightDom) {
        item.style.display = 'none';
    }
    const leftDom = document.querySelector(`#left${id}`);
    const rightDom = document.querySelector(`#right${id}`);
    // if (display === 'inline-block') {
    //     const styleSheet = document.styleSheets[0];
    //     const bodyDom = document.querySelector(`#body${id}`);
    //     const cssRules = Array.from(styleSheet.cssRules);
    //     const index = cssRules.findIndex(rules => {
    //         return rules.selectorText === '.focus-body';
    //     });
    //     const cssText = `.focus-body{height: ${bodyDom.offsetHeight - 3}px;}`;
    //     if (index > -1) {
    //         document.styleSheets[0].deleteRule(index);
    //     }
    //     document.styleSheets[0].insertRule(cssText);
    // }
    leftDom.style.display = display;
    rightDom.style.display = display;
};

/**
 * 控制显示组件名称
 * @param {*} index
 */
const mouseover = index => {
    const componentLeft = Array.from(document.querySelectorAll('.component-left'));
    componentLeft[index].style.display = 'inline-block';
};

/**
 * 控制隐藏组件名称
 * @param {*} index
 */
const mouseleave = index => {
    // if (components.value[index].focused) return;
    if (index == currentIndex.value) return;
    const componentLeft = Array.from(document.querySelectorAll('.component-left'));
    componentLeft[index].style.display = 'none';
};

/**
 * 计算组件名称偏移量
 * @param {*} index
 */
const computeTitlePosition = index => {
    nextTick(() => {
        const componentLeft = Array.from(document.querySelectorAll('.component-left'));
        const width = componentLeft[index].offsetWidth;
        componentLeft[index].style.left = `-${width + 8}px`;
        componentLeft[index].style.opacity = 1;
    });
};

/**
 * 组件获取焦点事件
 * @param {*} e
 * @param {*} index
 */
const componentFocusHandler = (element, index) => {
    currentIndex.value = index;
    passValueToParent(index, {
        id: element.id,
        name: element.component.name
    });
    // if (isNotEmpty(element)) {
    //     element.focused = true;
    // }
    changeToolDisplayHandler(element.id);
};

/**
 * 组件失去焦点事件
 * @param {*} e
 * @param {*} index
 */
// const componentBlurHandler = element => {
//     if (isNotEmpty(element)) {
//         element.focused = false;
//     }
//     changeToolDisplayHandler(element.id, 'none');
// };

/**
 * 向父页面传递被放置或被选中的组件的索引及全页面的数据
 * @param {*} e
 */
const passValueToParent = (index, element) => {
    // element.isOperate:是否进行删除、上移、下移组件内容（true：是，undefined：否）
    if (element.name != 'info') {
        iframeMessage.emit('passValueToParent', {
            name: element.name,
            index,
            isOperate: element.isOperate ? true : false,
            components: JSON.stringify(components.value)
        });
        // nextTick(() => {
        //     const componentCenter = Array.from(document.querySelectorAll('.component-body'));
        //     componentCenter[index].focus();
        // });
    } else {
        iframeMessage.emit('passValueToParent', {
            name: element.name,
            index,
            isOperate: element.isOperate ? true : false,
            form: JSON.stringify([element.form])
        });
    }
};
/**
 * 监听元素放置目标区域
 */
iframeMessage.on('drop', async e => {
    if (addIndex.value === -1) return;
    const id = components.value[addIndex.value].id;
    const component = getComponentByName(e.title, e.name);
    component.id = id;
    if (e.title == 'category') {
        component.options = {
            space: 0,
            tabs: '1',
            imgList: [
                { name: '', mutual: '', page: '选择页面', imgurl: '', id: '', chooseName: '', url: '', openimg: '' }
            ]
        };
    }
    if (e.title == 'images') {
        component.options = {
            space: 0,
            tabs: '1',
            cornerType: 1,
            btwSpace: 0,
            hwSpace: 0,
            imgSpace: 0,
            imgList: [{ name: '', mutual: '', page: '', imgurl: '', id: '', chooseName: '', url: '', openimg: '' }]
        };
    }
    if (e.title == 'product') {
        component.options = {
            space: 0,
            imgList: [],
            tabs: '2'
        };
    }
    if (e.title == 'groupbuy') {
        component.options = {
            space: 0,
            imgList: [],
            addType: 1,
            tabs: '1',
            contentList: [1, 2, 3, 4, 5, 6],
            groupType: [3, 4, 5],
            rule: 1
        };
    }
    if (e.title == 'seckill') {
        component.options = {
            space: 0,
            imgList: [],
            tabs: '1',
            contentList: [1, 2, 3, 4, 5]
        };
    }
    if (e.title == 'coupon') {
        component.options = {
            space: 0,
            imgList: [],
            tabs: '4',
            contentList: [1]
        };
    }
    if (e.title == 'text') {
        component.options = {
            space: 0,
            title: '标题名称',
            position: 1,
            description: '描述内容',
            titleColor: '#333333',
            descColor: '#666666',
            textColor: '#666666',
            content: '查看更多',
            show: true,
            name: '',
            mutual: '',
            page: '',
            imgurl: '',
            id: '',
            chooseName: '',
            url: ''
        };
    }
    if (e.title == 'wecom') {
        const res = await request('qwdefaultImg');
        component.options = {
            title: '添加企微客服',
            position: 1,
            description: '添加企微客服享专属福利',
            btnText: '去添加',
            btnColor: '#fe292b',
            qwCode: '',
            titleIcon: '',
            space: 0
        };
        component.options.titleIcon = res.data.qwDefaultLogo;
    }
    components.value.splice(addIndex.value, 0, component);
    nextTick(() => {
        changeToolDisplayHandler(getComponentId(currentIndex.value));
    });
    computeTitlePosition(addIndex.value);
    currentIndex.value = addIndex.value;
    removePlaceholderViewHandler();
    changeIframeHeight();

    passValueToParent(currentIndex.value, { id, name: e.title, isOperate: true });
});

/**
 * 修改组件配置
 */
iframeMessage.on('changeOptions', e => {
    if (e.name != 'info') {
        currentIndex.value = e.index;
        if (!e.isValid) {
            components.value[e.index].options = JSON.parse(JSON.stringify(e));
            if (components.value[e.index].options.imgList) {
                components.value[e.index].options.imgList = JSON.parse(components.value[e.index].options.imgList);
            }
            if (components.value[e.index].options.contentList) {
                components.value[e.index].options.contentList = JSON.parse(
                    components.value[e.index].options.contentList
                );
            }
            if (components.value[e.index].options.groupType) {
                components.value[e.index].options.groupType = JSON.parse(components.value[e.index].options.groupType);
            }
        }

        // 表单校验定位到组件
        if (e.isValid) {
            currentIndex.value = e.index;
            passValueToParent(currentIndex.value, {
                id: components.value[e.index].id,
                name: e.name
            });
        }
    } else {
        pageParam.data = JSON.parse(JSON.stringify(e));
        pageParam.data.pageCode = getUuid();
    }
    setTimeout(() => {
        changeIframeHeight();
    }, 200);
});

/**
 * 添加待放置区域
 */
const addPlaceholderViewHanlder = index => {
    removePlaceholderViewHandler();
    const PlaceHolderView = getComponentByName('PlaceHolderView');
    PlaceHolderView.id = getUuid();
    components.value.splice(index, 0, PlaceHolderView);
    addIndex.value = index;
};

/**
 * 移除待放置区域
 */
const removePlaceholderViewHandler = () => {
    addIndex.value = -1;
    let r = components.value.findIndex(item => item.component.name === 'PlaceHolderView');
    if (r > -1) {
        components.value.splice(r, 1);
    }
};

/**
 * 添加待放置区域组件
 */
iframeMessage.on('addMaskOver', e => {
    let index;
    if (e.status) {
        index = e.index;
    } else {
        index = e.index + 1;
    }
    // 去除支付结果页
    if (pageParam.data.isHomePage == 3) {
        index = index - 1;
    }
    addPlaceholderViewHanlder(index);
});
/**
 *页面保存
 */
iframeMessage.on('submit', () => {
    iframeMessage.emit('getAllParam', { ...pageParam.data, components: JSON.stringify(components.value) });
});
/**点击头部向父组件传递页面信息 */
const changeTOhead = () => {
    currentIndex.value = -1;
    nextTick(() => {
        const allRightDom = document.querySelectorAll(`.component-right`);
        const allLeftDom = document.querySelectorAll(`.component-left`);
        for (let item of allLeftDom) {
            item.style.display = 'none';
        }
        for (let item of allRightDom) {
            item.style.display = 'none';
        }
    });
    passValueToParent('', { name: 'info', form: pageParam.data });
};
/**操作栏 */
const operate = (e, num, index) => {
    e.stopPropagation();
    let nextIndex = -1;
    let currentElement = null;
    if (num == 1 && index != 0) {
        // 向上挪动一个
        let cur = components.value[index];
        let pre = components.value[index - 1];
        components.value[index] = pre;
        components.value[index - 1] = cur;
        nextIndex = index - 1;
        currentElement = components.value[nextIndex];
        passValueToParent(nextIndex, { id: currentElement.id, name: currentElement.component.name, isOperate: true });
    } else if (num == 2 && index < components.value.length - 1) {
        // 向下挪动一个
        let cur = components.value[index];
        let next = components.value[index + 1];
        components.value[index] = next;
        components.value[index + 1] = cur;
        nextIndex = index + 1;
        currentElement = components.value[nextIndex];
        passValueToParent(nextIndex, { id: currentElement.id, name: currentElement.component.name, isOperate: true });
    } else if (num == 3) {
        //删除当前组件
        components.value.splice(index, 1);
        if (components.value[index]) {
            addIndex.value = index;
        } else {
            // 删除最后一个组件
            addIndex.value = index - 1;
        }
        changeIframeHeight();
        if (components.value.length === 0) {
            changeTOhead();
            return;
        } else {
            currentElement = components.value[addIndex.value];
            nextIndex = index === components.value.length ? index - 1 : index;
        }
        nextTick(() => {
            changeToolDisplayHandler(getComponentId(nextIndex));
        });
        passValueToParent(nextIndex, { id: currentElement.id, name: currentElement.component.name, isOperate: true });
    }
};
// 根据索引获取元素id
const getComponentId = index => {
    const componentCenter = Array.from(document.querySelectorAll('.component-body'));
    return componentCenter[index].id.replace('body', '');
};
// 转换优惠券内容
const couponContent = obj => {
    const { couponPrerequisites, couponMatch, couponPrerequisitesAdditional, couponDiscountContent } = obj;
    const pre = [
        '无门槛，',
        `满${floatDivide(couponPrerequisitesAdditional, 100)}元，`,
        `满${couponPrerequisitesAdditional}件，`
    ];
    const num = [`全部商品`, `部分商品`, '部分商品'];
    return (pre[couponPrerequisites - 1] || '') + (num[couponMatch - 1] || '');
};
onMounted(async () => {
    const pageId = getUrlParam('pageId');
    shopName.value = getUrlParam('shopName');
    if (pageId) {
        // 编辑
        request('templateInfo', { id: pageId }).then(async res => {
            let data = [];
            for (let key in pageParam.data) {
                pageParam.data[key] = res.data[key];
            }
            // 获取支付结果默认图片
            if (pageParam.data.isHomePage == 3) {
                const data = await request('payresultImg');
                payresultImg.value = data.data.paymentImg;
            }
            let productIds = [];
            let seckillIds = [];
            let groupbuyIds = [];
            let couponIds = [];
            res.data.components.forEach(async (item, index) => {
                if (item.component.name == 'PlaceHolderView') {
                    // 删除因错误操作保存的待放置区域初始数据
                    res.data.components.splice(index, 1);
                    return;
                }
                delete item.component;
                item = { ...item, component: getComponentByName(item.options.name).component };
                if (item.component.name == 'product') {
                    productIds = [...productIds, ...item.options.imgList];
                } else if (item.component.name == 'seckill') {
                    seckillIds = [...seckillIds, ...item.options.imgList];
                } else if (item.component.name == 'groupbuy') {
                    if (item.options.addType == 1) {
                        //手动添加
                        groupbuyIds = [...groupbuyIds, ...item.options.imgList];
                    }
                } else if (item.component.name == 'coupon') {
                    couponIds = [...couponIds, ...item.options.imgList];
                }
                data.push(item);
            });
            let productData = [];
            let seckillData = [];
            let groupData = [];
            let couponData = [];
            if (productIds.length) {
                productData = await request('goodsList', { goodsId: productIds });
            }
            if (couponIds.length) {
                couponData = await request('couponList', { couponIds: couponIds });
            }
            if (seckillIds.length) {
                seckillData = await request('seckillList', { activityId: seckillIds });
            }
            if (groupbuyIds.length) {
                groupData = await request('seckillListManual', { activityId: groupbuyIds });
            }
            let getData = await Promise.all(
                data.map(async (item, index) => {
                    const name = item.component.name;
                    const imgLists = {
                        product: isNotEmpty(productData?.data) ? productData?.data : [],
                        seckill: isNotEmpty(seckillData?.data) ? seckillData?.data : [],
                        groupbuy: isNotEmpty(groupData?.data) ? groupData?.data : [],
                        coupon: isNotEmpty(couponData?.data) ? couponData?.data : []
                    };
                    if (name == 'product' || name == 'seckill') {
                        item.options.imgList.forEach((id, indexs) => {
                            let proItem = imgLists[name].filter(val => val.id == id);
                            if (proItem.length) {
                                item.options.imgList[indexs] = proItem[0];
                            } else {
                                item.options.imgList[indexs] = null;
                            }
                        });
                    }
                    if (name == 'coupon') {
                        item.options.imgList.forEach((id, indexs) => {
                            let proItem = imgLists[name].filter(val => val.id == id);
                            if (proItem.length) {
                                item.options.imgList[indexs] = proItem.map(
                                    ({ couponAcquiredNumber, id, couponInfo, couponId }) => {
                                        const item = {
                                            ...couponInfo
                                        };
                                        // receiveStatus:1表示已领完 2表示领取已达上限
                                        item.receiveStatus =
                                            item.couponTotal - couponAcquiredNumber == 0
                                                ? 1
                                                : item?.acquireLimit
                                                ? '2'
                                                : '';
                                        item.content = couponContent(item);
                                        item.id = id;
                                        item.couponId = couponId;

                                        return item;
                                    }
                                )[0];
                            } else {
                                item.options.imgList[indexs] = null;
                            }
                        });
                    }
                    if (name == 'groupbuy') {
                        if (item.options.addType == 1) {
                            item.options.imgList.forEach((id, indexs) => {
                                let proItem = imgLists[name].filter(val => val.id == id);
                                if (proItem.length) {
                                    item.options.imgList[indexs] = proItem[0];
                                } else {
                                    item.options.imgList[indexs] = null;
                                }
                            });
                        } else {
                            let typeList = ['have_group_goods_num', 'activity_end_time', 'activity_start_time'];
                            const groupAuto = await request('groupList', {
                                autogather: 1,
                                direction: 'desc',
                                activityType: item.options.groupType,
                                reorder: typeList[item.options.rule - 1]
                            });
                            item.options.imgList = isNotEmpty(groupAuto?.data) ? groupAuto?.data : [];
                        }
                    }
                    return item;
                })
            );
            // 过滤删除商品，当选择商品全部删除后，删除组件不再显示
            components.value = getData
                .map(item => {
                    item.options.imgList = item?.options?.imgList?.filter(fItem => fItem);
                    return item;
                })
                .filter(
                    item =>
                        !item.options.imgList ||
                        item.options?.imgList.length > 0 ||
                        (item.component.name == 'groupbuy' && item.options.addType == 2)
                );
            changeIframeHeight();
            passValueToParent('', { name: 'info', form: pageParam.data });
            nextTick(() => {
                const componentLeft = Array.from(document.querySelectorAll('.component-left'));
                componentLeft.forEach((item, index) => {
                    item.style.display = 'none';
                });
            });
        });
    }
});
onBeforeUnmount(() => {
    iframeMessage.destroy();
});
</script>
<style lang="scss" src="./style.scss" scoped></style>
